import { useEffect, useRef, useState } from 'react';

/**
 * To prevent interval being created and cleared every rendering.
 * https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies
 */
export function useTimer(callback: (date: Date) => void, ms: number = 1000): void {
  const latestCallbak = useRef(callback);

  useEffect(() => {
    const timerID = setInterval(() => tick(), ms);

    function tick(): void {
      if (latestCallbak.current != null) {
        latestCallbak.current(new Date());
      }
    }

    // Cleanup.
    return () => clearInterval(timerID);
  }, [ms]);
}

export function useEventListener(target: any, event: string, callback: (event: any) => void): void {
  useEffect(() => {
    target.addEventListener(event, callback);

    return () => target.removeEventListener(event, callback);
  }, [target, event, callback]);
}

export function useWindowInnerSize(
  param?: { heightOffset?: number | null; widthOffset?: number | null } | null,
): { height: number; width: number } {
  const defalutOffset: number = 0;
  const [height, setHeight] = useState<number>(
    window.innerHeight - (param?.heightOffset ?? defalutOffset),
  );
  const [width, setWidth] = useState<number>(
    window.innerHeight - (param?.widthOffset ?? defalutOffset),
  );

  const size = {
    height: height,
    width: width,
  };

  useEventListener(window, 'resize', () => {
    setHeight(window.innerHeight - (param?.heightOffset ?? defalutOffset));
    setWidth(window.innerWidth - (param?.widthOffset ?? defalutOffset));
  });

  return size;
}
